Repository navigation
Research: segmented, resumable reloads (proof of concept) - #2251
Draft
sunzenshen wants to merge 67 commits into
Draft
sunzenshen wants to merge 67 commits into
sunzenshen wants to merge 67 commits into
Conversation
CNEORules::Think() refreshes the ghoster index only after every entity has thought, so in the frame after the ghost carrier disconnects (a kick, neo_bot_quota 0) the boundary's Think() still reads the old index. UTIL_PlayerByIndex() then returns null for the freed edict and GetFlags() crashes the server. Skip the position update when the player is gone, the same way GetGhostMarkerPos() already does. The juggernaut branch reads its index the same way and gets the same check.
CleanUpMap removed each player's neo_predicted_viewmodel_muzzleflash but kept the neo_predicted_viewmodel it is parented to. A bot with a pending class change calls RequestSetClass from CNEOBot::Spawn before CBasePlayer::Spawn recreates the viewmodels, so GiveDefaultItems -> Weapon_Switch dereferenced the removed muzzle flash viewmodel and the server crashed (bot_changeclass, then mp_restartgame). Preserve it like the viewmodel, so the player keeps one for life.
The Tachi and Milso viewmodels carry a node graph from HL2's pistol, so a reload started from the lowered pose (during a sprint) played the lowtoidle transition first. DefaultReload took that 0.37-0.40 s transition as the reload length, and the server refilled the magazine after about 0.6 s with no reload animation. Skip transitions for ACT_VM_RELOAD as SetIdealActivity already does for the draw, so the reload plays at once and lasts its own 2.1 s.
The Tachi and Milso viewmodels have an idle01empty sequence with the slide held back, which neo never played: an emptied pistol held its last fire frame for 2.0 s and then idled with the slide forward. The original NEOTOKYO holds the slide back from the end of the last shot until the reload. Send ACT_VM_IDLE_EMPTY for ACT_VM_IDLE while the clip is empty, as the SDK crossbow does, and go to it as the emptying shot's sequence ends. Models without the sequence are unchanged.
The Tachi and Milso viewmodels ship a drawempty sequence, the normal draw with the slide held back, but it carries no activity, so an empty pistol drew with the slide forward and only pulled it back as the empty idle faded in. Pick drawempty by name in Deploy when the clip is empty. Models without it, and loaded draws, are unchanged.
A reload credited the magazine only when the whole reload animation ended, 0.2 to 0.7 s after the last click of the reload sound. Switching weapons in that window dropped the reload, though the gun sounded done. Each gun script now names its ReloadReadyTime: the last loud click of its reload sound, rounded up to the animation frame. Where the charging handle is home later (Jitte, SRM, MPN, AA13, PZ), the script comment names that time as the alternative value. The reload completes there and the rest of the animation plays on. Guns without the key (Supa7) keep the animation length.
Move the player animation back onto CBasePlayerAnimState, the 2006 SDK base classic NEOTOKYO is built on, which neo compiles but did not use. CNEOPlayerAnimState replaces CHL2MPPlayerAnimState and takes CMultiPlayerAnimState out of the build (the files stay on disk). The base gives classic's torso blend by speed, constant leg ground speeds, the 3 s face-front timer and its feet rules. The new class adds the run legs only while sprinting, the jump held until a drawn landing, one gesture layer for fire, reload, grenade and detpack events, the lean rule, the NeotokyoRebuild#2108 transitioner reset, and a face-front timer counted from the last squared frame so server and client agree. Client-side animation and the network excludes from NeotokyoRebuild#653 are kept.
Keep the end of the reload animation as the time the gun can fire again, as before this branch, and only load the magazine early: the owner stays busy until the animation ends, and the weapon loads the magazine from ItemBusyFrame once the reload's ready time has passed. A switch after the last click keeps the ammo; firing, aiming and the sprint lower still wait for the animation to end. The script key is now ReloadReadyBeforeEnd, the time from the last reload click to the end of the reload animation, and the ready time is that much before the end of the reload sequence actually played, clamped to the reload start. The ready time is networked and predicted so the client loads the magazine on the same frame.
Four entries, weapon_zr68.reload_{drop,seat,slap,bolt}, for the
per-phase reload pieces sliced from zr68_reload.wav (neoAssets
research-reload-phases 86ebd7f+). CHAN_ITEM, so a later piece from
the same weapon replaces an unfinished one. No code plays them yet.
A weapon script may list, per reload sequence, the phases the sequence carries (drop, seat, slap, bolt), each with the time it counts and the sound piece that goes with it, and whether a partial reload keeps a chambered round. Data only: nothing reads it yet. The ZR68S gets its block, generated from ntre's segments.csv for the sequences in neoAssets research-reload-phases 86ebd7f.
A weapon whose script lists ReloadPhases reloads as a linear sequence of phases instead of one refill at the end. The drop leaves only a chambered round in the gun (the old magazine is gone), the seat loads one magazine from the reserve, the bolt chambers a round on a dry reload. A partial reload of a 30-round gun ends at 31. The phases credited so far survive a weapon switch; once the weapon is drawn again the reload resumes and credits only the phases left. Until the resume sequences are selected, the shipped reload plays and the earlier phases are skipped. The wait to fire stays the length of the animation that plays. Weapons without the block (Supa7, SMAC, the rest for now) take the previous path unchanged. The ZR68S drops ReloadReadyBeforeEnd: its seat credit replaces it.
The resume sequences' reaches now keep the hand at the shipped reach pace (neoAssets research-reload-phases b863e63), so each resume credits its phases 0.5 s later than before.
A reload whose phases name sound pieces plays each piece when its time in the playing sequence comes (each file starts 0.02 s before its first transient), instead of the one reload wav at the start. Phases credited before a switch do not play their pieces again, and a switch stops the pieces still sounding. Also adds GetMaxRoundsInGun, the magazine plus a chambered round, for the ammo HUD.
A weapon that keeps a round in the chamber on a partial reload shows one more bullet slot, so a partial reload of a 30-round magazine reads 31/31. During a dry reload the last slot stays empty until the bolt chambers a round.
The ZR68S script lists the phases of draw_resume_drop_{dry,partial}
(neoAssets research-reload-phases c61699a), the resume that starts
from the draw after the magazine dropped. A weapon may now list up to
12 reload sequences.
The drop piece now starts with the hand's first soft sounds (neoAssets research-reload-phases c20c13b), so its first transient is at 0.146 s.
A reload with phases plays the sequence for what is left: the partial reload when a round is chambered, and after a switch the resume that starts with the hand reaching back to the next phase (from the drop, the seat or the slap, dry or partial). After the magazine dropped, the resume starts in the draw itself, which brings the fresh magazine up out of view. A model without the sequence plays the shipped reload and credits only the phases left, as before.
When the bullet row overflows into a + mark, the mark is filled for a full gun; with the chambered round counted, full is the magazine plus one.
The ZR68C reloads in phases like the ZR68S (same bones, same sound pieces), with its sequences from neoAssets research-reload-phases 5edfe2e. Its ReloadReadyBeforeEnd goes: the seat credit replaces it.
The ZR68L reloads in phases with sequences and sound pieces from
neoAssets research-reload-phases d18409d; its own wav's pieces join
the sound script as weapon_zr68l.reload_{drop,seat,slap,bolt}. Its
ReloadReadyBeforeEnd goes: the seat credit replaces it.
Both MX guns reload in phases with the sequences and sound pieces of neoAssets research-reload-phases 0c24082 (the seat rattle sounds at the silent magazine seat, 0.27 s before its place in the wav); the pieces join the sound script as weapon_mx.reload_*. Their ReloadReadyBeforeEnd goes.
A phase may name sound2 / at2 beside sound / at, for a phase whose sound comes in two pieces timed apart: the M41's seat has a tap rattle that belongs at the silent seat and tap clicks that stay on the tap.
The M41 guns reload in phases with the slap as its own phase, with the sequences and sound pieces of neoAssets research-reload-phases 3e6d86e. The seat carries two pieces: the tap rattle at the silent magazine seat and the tap clicks on the tap. Their ReloadReadyBeforeEnd goes.
A phase's sound piece was only considered until the phase was credited, so pieces timed after their credit (the M41's slap click, its tap clicks) never played. Pieces now play on their own times; those of phases credited before the sequence started, and a partial reload's bolt, are marked done when the sequence starts.
Both Jitte guns reload in phases with the sequences and sound pieces of neoAssets research-reload-phases d58ceec. Their ReloadReadyBeforeEnd goes.
The SRM, SRM-S, MPN and unsilenced MPN reload in phases with the sequences and sound pieces of neoAssets research-reload-phases f6e2f9e. Their ReloadReadyBeforeEnd goes.
The AA13 and PZ reload in phases with the sequences and sound pieces of neoAssets research-reload-phases b5aaa7a; the PZ's drum latch is its slap phase. Their ReloadReadyBeforeEnd goes.
Phase reloads and draw-resumes set PLAYER_RELOAD, which does nothing under NEO, so other players saw no reload gesture (the shipped reload path sends the animation event). Send PLAYERANIMEVENT_RELOAD as the Supa7 does. A drop or a death now also stops the reload's sound piece.
A resumed reload played the full reload gesture from the start, and a partial or interrupted one let it run on past the reload. Send the gesture's start cycle in the animation event's spare data (the credit time of the last completed phase in the full reload, as a fraction of it; 0 for a fresh reload and the draw-resume), and end the gesture with PLAYERANIMEVENT_RELOAD_END when the reload ends, is holstered or the weapon is dropped. The animation state starts the layer at that cycle and resets the slot on the end event. No new networked fields.
The partial and resume sequences were looked up on the weapon entity, which on the client carries the world model: the lookup failed there, so the client predicted the shipped reload while the server played the partial or resume sequence, and the resumed gesture started from 0 on the owner's own client. Look them up, and time them, on the owner's viewmodel on both sides.
The table index was sent in 4 signed bits (-8..7), but a gun has up to 12 tables and the ZR68, MX, M41 and PZ guns use index 8 for draw_resume_drop_partial. The owner's client read another table, so it predicted the wrong credits and replayed the drop sound piece on a draw-resume after a partial reload's drop.
The tube's capacity was the clip size minus a live chambered round, so the gun held 7 in all, as on master and in classic. The tube now holds the script's clip size (7) and the chamber one more round beside it: a partial reload ends at 8, a dry reload loads 7 and racks one up (chamber + 6, 7 in all) with room for a one-shell top-off, and the standalone rack is offered when the tube holds 7. GetMaxRoundsInGun becomes virtual so the ammo HUD draws 8 slots for the Supa7. GetMaxClip1 stays 7 (the tube) for bots and the base code, as the magazine size does for the other chambered guns.
A dry reload switched away from before its end rack leaves shells in the tube and the chamber empty. The trigger then fired anyway, and the shot's own pump fed the tube's top shell, so that shot cost no round (7 in the gun before and after). The trigger now racks the pump once (the standalone rack) and the next press fires. Master and classic fire at once in this state and pump on the next reload; this rack only ever delays the shot, never brings it earlier.
A chambered slug blocked every shell reload, a rule from master's single clip count, where the slug was simply the next round to fire. With the chamber outside the tube, shells now load into the tube behind a chambered slug and the reload ends without a rack, so a gun with a slug up still tops off to 8. Loading a second slug onto a chambered one stays refused, so a slug is never racked out by accident.
The shot that emptied a Tachi or Milso played its normal fire sequence, whose slide closes within 0.2 s, and the slide went back only when the empty idle followed 0.4 s later. Both pistols ship a dry fire sequence that is a shot's kick with the slide held back throughout, ending on the empty idle's pose, so the last round's shot plays that instead.
A reload always played the reload sequence, whose slide is forward from its first frame, so the slide of an empty pistol closed as the reload began. The Milso ships a reload for an empty gun (ACT_VM_RELOAD_EMPTY) that keeps the slide back until its release near the end, the same length as the reload; an empty weapon now plays it where the model has one.
# Conflicts: # src/game/shared/neo/weapons/weapon_neobasecombatweapon.cpp
anim-sdk-base deletes hl2mp_playeranimstate.*, where this branch had the reload gesture hooks. They move to CNEOPlayerAnimState: the RELOAD_END event, the resumed reload's start cycle from nData, and the end of the reload gesture on RELOAD_END. # Conflicts: # src/game/shared/hl2mp/hl2mp_playeranimstate.cpp # src/game/shared/hl2mp/hl2mp_playeranimstate.h
A dry Milso or Tachi reload interrupted after the seat has rounds in the magazine but none chambered, and its slide is still back: the resume is the slide release alone. The draw and the idle chose their empty sequences by an empty magazine only, so the slide went forward on the draw and snapped back when the release resumed.
The NEO anim state ends a gesture at once, so a reload cut short by a partial magazine's end or a death snapped the third-person gun from the reload pose to the aim pose in one frame. Fade it out over 0.2 s as the HL2MP gesture slots did.
A switch mid-reload ended the third-person reload gesture at once, the same snap from the reload pose to the aim pose that a reload ending early had. Fade it out over 0.2 s too; a fire or throw gesture still stops at once on a switch.
The clip counts the chambered round on guns with reload phases. Four getters split it out for the HUD and the fire rules: whether the gun has a chamber slot, whether a live round is in it, the rounds in the magazine and the magazine's capacity. The Supa7 answers from its tube and chamber.
A gun with a chamber draws its magazine row and, at the row's right end, one larger glyph for the chamber: lit while a live round is chambered, in the empty color otherwise. The row's overflow mark now counts the magazine alone. Number mode shows 29+1/30.
A trigger press during a reload with phases, while a round can fire, ends the reload where it is and fires on the same tick: before the old magazine drops it keeps the partly empty magazine, after the fresh one is seated it keeps what was loaded. A dry reload before its bolt, and a gun whose magazine is out, ignore the press. Sound pieces of phases not reached stop; the first shot blends in with fire_blend where the model has it. One entry point, TryFireDuringReload, called from ItemBusyFrame; RELOAD_FIRE_INTERRUPTS turns it off.
With sv_neo_reload_chamber_shot on, a trigger press while a partial reload has the magazine out plays fire_chamber_onehand: the gun flicks to the hold one-handed, the bullet fires at the table's fire_at, and the reload goes on dry from the insert. A switch during the flick cancels the shot. A model without the sequence, the SRS, and a gun with an empty chamber refuse the shot. The shot keeps the reload's timers, animation and gesture. The cvar defaults to 0 until every gun's model has the sequence; the weapon scripts carry the sequence's phase tables, generated from segments.csv.
Contributor
Author
|
This PR is open for local experimentation, but is probably going to change a lot code wise for initial iterations. It may be a better to prioritize smaller PRs like #2248 as incremental improvements to the animation workflow. |
The large chamber glyph at the row's end crowded the ammo counter. The fire-mode glyph already carries a small round icon (a bullet, or a shell on the Supa7) above its letter; it now shows the chamber instead: the filled color while a round is chambered, the empty color otherwise, with the letter in the text color as before. The row keeps counting the magazine alone. Guns without a chamber slot are drawn as before.
Every gun with a chamber now has its fire_chamber_onehand sequence, so sv_neo_reload_chamber_shot defaults to 1.
After a shot the SRS chamber holds a spent case until the bolt cycle brings the next round home, so the chamber icon dims at the shot and lights when the bolt is home, with the magazine row dropping by one then instead of at the shot. The moment comes from a "charge" phase table in the weapon script (the Bolt bone home in the charge sequence, frame 25). A quick switch or a reload cancels the bolt cycle as before and the round counts as chambered. Ammo and fire timing are unchanged.
The shot already racks the pump in the gun's state; the HUD now shows the chamber dim and the fed round still in the tube until the fire animation's pump is home, never later than the next shot is allowed. The pump moments come from the weapon script (ChamberAfterShot 0.600 for a shell, ChamberAfterSlugShot 1.000 for a slug: the Pump bone home in altfire f18 and fire f30). Ammo and fire timing are unchanged.
On a gun whose reload slaps or taps the magazine home, the trigger now ends a partial reload only after the slap credit, not at the seat, so a cancel skips only the steps already complete and stays close to the full reload time. Guns without a slap still end at the seat; the rule reads the reload's own phase table.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft. One branch that combines every reload idea of proposal 0057 so reviewers can see them together and say
which parts to split into their own PRs. It is also the bundle of all our pending fixes: Option A #2244
(player animation on the SDK base anim state), #2245, #2248 (with its slide fixes), #2249, #2246, #2250, and the
Tachi reloadempty asset (NeotokyoRebuild/neoAssets#170), so one build previews them all together. It needs the
matching neoAssets branch (
research-reload-phases), which carries the recompiled viewmodels and the sound pieces.Policy: whenever one of the bundled PRs merges, this branch is rebased onto master, the merged commits drop out and
any changed assumption (a sequence name, an activity, a hook) is resolved here, so the branch shrinks to what is not
yet merged.
What it does
slap), bolt (dry reloads only). Each phase counts at its point in the animation, listed per sequence in the weapon
script (
ReloadPhasesblock, generated from a table so assets and script agree). The drop leaves only achambered round, the seat loads one magazine from the reserve, the bolt chambers a round.
reload_partial(no bolt) and ends atmagazine + 1 (30 + 1 = 31); a dry reload ends at 30. The wait to fire is the length of the animation that plays.
the hand reaching from the hold to that phase's grab pose. After the drop the resume starts in the draw itself
(
draw_resume_drop_*): the gun comes up one-handed with the support hand and fresh magazine out of view, then swoopsin. Always on, no option.
played at its own time (several moved to meet the animation, below); a switch stops them; resumed phases do not
replay finished pieces.
reloademptywith the slide release (the Milso's shipped one, a built one for the Tachi); apistol switched away after the seat resumes with the slide release alone. The Kyla has no chamber: its reload
keeps the live rounds and fills only the empty slots, as today (reload at 4: 6, reserve -2).
a rack ejects the chamber and feeds the top item; the shell insert plays at 1.47x so each one finishes within the
unchanged 0.5 s; a reload press with the tube full racks once (
racksequence).mark, the mark is filled only when the gun is full.
draw-resumes. A resumed reload starts the gesture where the resume starts (the credit time of the last finished
phase over the full reload's length, sent in the event's data), and the gesture ends with the reload: at its end,
on a switch, a drop or death (
PLAYERANIMEVENT_RELOAD_END), so a cancelled reload stops on the body too.What the bundle adds beyond the bundled PRs
hl2mp_playeranimstate.*, so the third-personhooks above live in
CNEOPlayerAnimState:PLAYERANIMEVENT_RELOAD_END, the resumed reload's start cycle from theevent data, and the end of the reload gesture (in the Animate players on the SDK base player anim state #2244 merge, a75be2a).
gesture at once, so a partial reload's early end, or a switch mid-reload, snapped the third-person gun from the
reload pose to the aim pose in one frame; it now fades out over 0.2 s as the HL2MP gesture slots did. On a switch
this deliberately differs from Animate players on the SDK base player anim state #2244, which stops every gesture at once on a weapon change (a fire or throw gesture
still does here).
magazine but none chambered, with the slide still back. The draw and the idle now use their empty sequences for
that state too (
drawempty,idle01empty), so the slide no longer goes forward on the draw and snaps back when theslide release resumes. Pistols only.
AE_MUZZLEFLASHon theTachi's fire sequences; the recompiled Tachi has them again, as in the neoAssets Tachi reloadempty PR.
Commits, grouped for splitting
Base, merged as is: Finish reloads at the last reload click #2245
reload-ready-at-cue(ba69cc1),vm-empty-drawincl.vm-empty-slide-lock(63733b3, and its slide fixes in 0dd0c46),
fix-pistol-sprint-reload(9f99ae2), Keep the muzzle flash viewmodel on map cleanup #2246fix-muzzleflash-class-change(c5e4349), Null-check the objective carrier in ghost boundary #2250fix-ghost-boundary-null-player(9a06a56), Animate players on the SDK base player anim state #2244anim-sdk-base(a75be2a, with the gesture hooks ported).Phase machine: 5058940 Parse the ReloadPhases weapon-script block; 5f5fc36 Track reload phases and credit ammo
per phase; 4a54e94 Select partial and resume reload sequences by name (with the draw-resume in
Deploy).Sound pieces: a7a5ac2, 8d7daa2 Play the reload sound in per-phase pieces; ef49e0f Allow a second sound piece
per reload phase; 35b2bf3 Play a phase's sound pieces after its credit too.
HUD: 545bb3e Show the chambered round on the ammo HUD; d4df589 Fill the HUD's overflow mark for a full gun.
Pistols: 5f64639 Reload an empty pistol with its slide release; 38ce827 placeholder slide-release sound;
faa65c6 Top up a revolver's cylinder instead of emptying it.
Per-gun data (weapon scripts and sound entries only): ZR68S 9d3c2af 39ec946 46c405c, ZR68C 10c0013, ZR68L
0e37c6f, MX 897e3e1, M41 146289f, Jitte eda7000 12b1de8, SRM / MPN f24237a, AA13 / PZ 6f66303, SRS
fdaef0b, Milso / Tachi c12716e, Kyla 402163a.
Supa7: bde9bf4 tube, chamber and pump as state; cee96d3 insert at the shell pace; 165e63b slug insert at its
own pace; 9323316 rack on a reload press with the tube full.
Third person: 5d3644b Show the reload gesture for phase reloads (also stops the sound pieces on a drop and on
death); 74cac6b Start the reload gesture where a resumed reload resumes; 6040298 Look up reload sequences on
the viewmodel (the client predicted
reloadfor a partial and 0 for the resume start, because the weapon's ownmodel on the client is the world model).
Bundle: b7b8a08 Draw and idle a pistol with its slide back until the release; 0d8e2b6 Fade out a reload
gesture that ends early; 4788a5e Fade out a reload gesture on a weapon switch.
Splits that stand alone: group 4 (HUD) needs 2; group 5 needs 2; group 7 is independent of 2-6.
Per-gun timings (animation length = wait to fire)
Resumes after the drop through the draw include the draw (0.8 s on most guns), so they replace draw + reload.
Tests
Credits, switches and resumes on every permutation of every gun, filmed in game with sound (listen server,
neo_reloadlog): every take played the planned sequence and ended at the expected count.Client prediction (ZR68S): every credit predicted on the client at the same time with the same count.
Debug, 12 bots, 1 round: ntre_dawn_ctg, ntre_threadplate_ctg, ntre_isolation_ctg, ntre_bullet_tdm: no asserts.
Bot census (8 spawns on ntre_threadplate_ctg, every class and XP tier): 16 guns reloaded through the phases (MX 72
reload sequences, ZR68S 43, Kyla 40, ...), resumes in normal play, every reload ended or was cancelled by a switch.
Third person (ZR68S, listen server,
thirdperson): gesture start on the server and the owner's client for everyphase sequence, with start data 0 (fresh, draw-resume), 0.493 (after the seat), 0.629 (after the slap); the end at
the sequence end and at each switch. Death mid-reload (
killat the slap): gesture end at the death, no bolt pieceafterwards. Spectating bots (ntre_dawn_ctg, chase and in-eye): the spectator received each start and end the server
sent for the watched bot. Bot census (4 spawns, threadplate): gesture starts = phase starts in every match.
Bundle build (all of the above merged): Milso and Tachi permutations re-filmed with sound; the resume after the
seat on a dry pistol now plays
drawempty->reload_from_seat_dry->idle01, and the slide-release piece plays.Third person on Option A (ZR68S): resumes start at cycle 0.496 (after the seat) and 0.632 (after the slap); a
partial ends early at ~0.92 and fades over 0.2 s, and a switch mid-reload fades over 0.2 s too. Debug, 12 bots, 1 round on the same four maps: no asserts. Bot
census (8 spawns, threadplate, Release): 8/8 clean, no reload stalls (Tachi 32
reloadempty, Milso 26, twoslide-release resumes each).
Open items
Option A's own cases (jump pose, upper-body blend, sprint legs, feet squaring up) were not re-filmed on the bundle
build; Animate players on the SDK base player anim state #2244's clips stand for them.
Pistol slide-release sound is a placeholder (a slice of the game's MP5 slide sound); needs a proper recording.
Holstering after an interruption past the drop briefly fades the magazine back into the gun as it lowers (0.3 s).
Supa7 shell-shot pump sound: parked; the same in classic.
Stealth option: some players may not want a resume (and its sound) started for them on switch-back; a later option
beside
cl_autoreload_when_empty.Behavior changes to decide: loading a Supa7 slug with a shell chambered racks the shell out (lost); the HUD reads a 30-round gun as not full (31 is full).
Supa7 per-shell shell/slug glyphs on the HUD (the chamber icon already shows which is chambered).
Decisions and where they come from
magazine contact then straight to the hold, resume = reach to the grab pose: user, 2026-10-15 (proposal 0057
research, sections 7-9).
1.47x (classic restarts every 0.5 s too), shell-shot pump sound parked: user, 2026-10-15.
user, 2026-10-15 evening.
Videos
Per gun, every permutation (dry, partial, resume after the drop / seat / slap) with sound and HUD:
zr68s,zr68c,zr68l,mx,mx_silenced,m41,m41s,m41l,jitte,jittescoped,srm,srm_s,mpn,mpn_unsilenced,aa13,pz,srs,milso,tachi,kyla,supa7(review-media/<gun>-permutations/all.mp4in ntre proposals/0057; Milso and Tachi on the bundle build:
review-media/<gun>-permutations-bundle/) and the overview reelreview-media/research-reload-overview.mp4. Third person, master thenresearch for each take (fresh dry, partial, resume after the seat, resume after the slap, death mid-reload):
review-media/zr68s-thirdperson-gesture.mp4; spectating bots:review-media/zr68s-spectator-gesture.mp4.Assets
The models and sound pieces are in NeotokyoRebuild/neoAssets#169 (neoAssets branch
research-reload-phases).Chamber shot and fire during a reload (added 2026-10-16, research only)
A behavior change from master and possibly a balance change, kept on this branch to try it out.
chambered and dim when not. After a dry reload the magazine row lights at the seat, and the round lights at the
charging-handle pull with the magazine one lower. The SRS dims it at a shot until the bolt is home, the Supa7 until
the pump is home.
after the last step that loads the gun: the magazine tap on guns that have one, else the seat (a2ad518), so it
skips only steps already done (0.3-0.9 s of tail on a partial reload).
fire_chamber_onehand, a shortflick to center, the shot 0.133 s after the press, 0.200 s on the MPN), then the rest of the reload is a dry reload.
This part is
sv_neo_reload_chamber_shot(default 1, a toggle on purpose so it can be compared and turned off); at0 the trigger is ignored while the magazine is out, as before.
round by default"; the trigger rules come out with "Let the trigger end a reload before the drop or after the seat"
and the neoAssets commits with the one-handed sequences.
Debug runs with asserts=0. Not tested: network lag.
the time already spent before its checkpoint. Measured: 11 resume sequences are early by 0.03-0.63 s when the draw
is not counted, none when the 0.8 s draw is counted;
proposals/0057-reload-cue-timing/timing-rule-partial.mdinthe ntre notes has the table. Not changed yet.